import os

import cv2
import numpy as np
import YD_C.COM.common as common


def showImage(dealImage):
    cv2.imshow("image", dealImage)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


def saveImage(path, image):
    cv2.imwrite(path, image)


# 图像增强
class imgD:
    def __init__(self, inputimage):
        self.input_image = inputimage

    def adjust_contrast_brightness(self, alpha=1.6, beta=12):
        # 对图像进行亮度和对比度的线性变换
        adjusted = cv2.convertScaleAbs(self.input_image, alpha=alpha, beta=beta)
        return adjusted

    def histogram_equalization(self):
        # 对图像进行直方图均衡化
        return cv2.equalizeHist(self.input_image)

    def adaptive_histogram_equalization(self):  # 效果ok
        # 对图像进行自适应直方图均衡化
        clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
        image = clahe.apply(self.input_image)
        return image


# 模糊处理
class imageSharpen:
    def __init__(self, image):
        self.image = image

    def lapulasi(self):
        blurred1 = cv2.GaussianBlur(self.image, (3, 3), 0)  # 先进行高斯模糊
        laplacian = cv2.Laplacian(blurred1, cv2.CV_64F)
        sharpened = cv2.convertScaleAbs(self.image - laplacian)
        self.image = sharpened

    def sobel(self):
        sobel_x = cv2.Sobel(self.image, cv2.CV_64F, 1, 0, ksize=3)
        sobel_y = cv2.Sobel(self.image, cv2.CV_64F, 0, 1, ksize=3)
        gradient = np.sqrt(sobel_x ** 2 + sobel_y ** 2)
        sharpened = cv2.convertScaleAbs(self.image - gradient)
        self.image = sharpened

    def scharr(self):
        # 应用Scharr算子计算x、y方向的梯度
        gradient_x = cv2.Scharr(self.image, cv2.CV_64F, 1, 0)
        gradient_y = cv2.Scharr(self.image, cv2.CV_64F, 0, 1)
        # 转换为8位整型
        gradient_x = cv2.convertScaleAbs(gradient_x)
        gradient_y = cv2.convertScaleAbs(gradient_y)
        # 组合x、y方向的梯度
        self.image = cv2.addWeighted(gradient_x, 0.5, gradient_y, 0.5, 0)

    def canny(self):
        # 步骤1：高斯模糊
        blurred3 = cv2.GaussianBlur(self.image, (5, 5), 0)
        # 步骤2：计算梯度
        gradient = cv2.Canny(blurred3, threshold1=30, threshold2=100)
        return gradient

    def gama_transfer(self, power1=1):
        if len(self.image.shape) == 3:
            self.image = cv2.cvtColor(self.image, cv2.COLOR_BGR2RGB)
        self.image = 255 * np.power(self.image / 255, power1)
        self.image = np.around(self.image)
        self.image[self.image > 255] = 255
        self.image = self.image.astype(np.uint8)

    def enhance_image_with_gradient_threshold(self):
        # 使用Sobel滤波器计算水平和垂直方向上的梯度
        gradient_x = cv2.Sobel(self.image, cv2.CV_64F, 1, 0, ksize=3)
        gradient_y = cv2.Sobel(self.image, cv2.CV_64F, 0, 1, ksize=3)
        # 计算梯度幅值和方向
        gradient_magnitude = np.sqrt(gradient_x ** 2 + gradient_y ** 2)
        # gradient_direction = np.arctan2(gradient_y, gradient_x)
        # 对梯度幅值进行阈值处理，将较小的像素值设为0，较大的像素值保持不变
        threshold_value, thresholded_magnitude = cv2.threshold(gradient_magnitude, 0, 255, cv2.THRESH_TOZERO)
        # 将图像进行归一化，在增强边缘后与原始图像进行融合
        normalized_magnitude = cv2.normalize(thresholded_magnitude.astype(np.float32), None, 0.0, 1.0, cv2.NORM_MINMAX)
        # 将增强后的边缘图像与原始图像进行融合
        enhanced_image = cv2.addWeighted(self.image, 1.0, normalized_magnitude, 0.5, 0)
        return enhanced_image


# 滤波的方法
class filterGub:
    def __init__(self, image):
        self.image = image

    def bfltGray(self):
        self.image = cv2.bilateralFilter(self.image, d=7, sigmaColor=95, sigmaSpace=95)


# 二值化的方法
class thresholdDeal:
    def __init__(self, image):
        self.image = image
        self.resImage = None

    def otsu(self):
        _, self.resImage = cv2.threshold(self.image, 0, 255, cv2.THRESH_OTSU)

    def trunc(self):
        _, self.resImage = cv2.threshold(self.image, 0, 255, cv2.THRESH_TRUNC)

    def binary(self):
        _, self.image = cv2.threshold(self.image, 120, 230, cv2.THRESH_BINARY)


# 根据当前图片的分布直方图  和原图进行对比，得到的新图
class compareImage:
    def __init__(self, srcImg):
        self.srcImg = srcImg
        self.diffImg = None
        self.calcImg = None
        self.mostGray = None
        self.grayImg = None
        self.whiteImg = None
        self.blackImg = None

    def calchist(self):
        # 获取原始图像的灰度值分布直方图
        hist = cv2.calcHist([self.srcImg], [0], None, [256], [0, 256])
        # 计算累积直方图
        cdf = hist.cumsum()
        # 归一化累积直方图
        cdf_normalized = cdf / cdf.max()
        # 生成随机数列
        random_values = np.random.rand(self.srcImg.shape[0] * self.srcImg.shape[1])
        # 根据灰度值分布对随机数列进行排序
        sorted_values = np.interp(random_values, cdf_normalized, np.arange(0, 256))
        # 将排序后的值重塑为与原始图像相同大小的矩阵
        self.calcImg = np.reshape(sorted_values, self.srcImg.shape).astype(np.uint8)

    def imgDiff(self, input_img):
        self.diffImg = cv2.subtract(input_img, self.srcImg)

    def maxGray(self):
        histogram = np.bincount(self.srcImg.flatten(), minlength=256)
        self.mostGray = np.argmax(histogram)
        print("most gray:", self.mostGray)

    def createWhite(self):
        self.whiteImg = np.zeros((self.srcImg.shape[0], self.srcImg.shape[1]), dtype=np.uint8)
        self.whiteImg.fill(255)

    def createBlack(self):
        self.whiteImg = np.zeros((self.srcImg.shape[0], self.srcImg.shape[1]), dtype=np.uint8)

    def createrGrayImg(self):
        self.grayImg = np.zeros((self.srcImg.shape[0], self.srcImg.shape[1]), dtype=np.uint8)
        self.grayImg[:, :] = self.mostGray

# image = cv2.imread("C:/Users/1234/Desktop/yolotestdata/23.05.26/yuan+yuanhuanzhen/1.bmp", 0)
# threshold = thresholdDeal(image)
# threshold.binary()
# showImage(threshold.resImage)

# basePath = "C:/Users/1234/Desktop/yolotestdata/23.05.26/yuan+yuanhuanzhen/"
# savePath = os.path.join(basePath, "binarysobel/")
# if not os.path.exists(savePath):
#     os.makedirs(savePath)
#
# for cr in range(1, 100):
#     crname = str(cr) + ".bmp"
#     imagePath = os.path.join(basePath, crname)
#     save_path = os.path.join(savePath, crname)
#     input_image = cv2.imread(imagePath, 0)
#     # 初始化图像增强类
#     imageD = imgD(input_image)
#     image2 = imageD.adjust_contrast_brightness()
#     blurred = common.add_guassianBlur(image2)
#     # media_blurred = common.add_median_filter(blurred)
#     imgSharpen = imageSharpen(image2)
#     imgSharpen.sobel()
#     # imgSharpen.gama_transfer()
#     # filterG = filterGub(imgSharpen.image)
#     # filterG.bfltGray()
#
#     threshold = thresholdDeal(imgSharpen.image)
#     threshold.binary()
#
#     saveImage(save_path, threshold.image)
